import { HttpException, HttpStatus, Injectable } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { FindManyOptions, Like, Repository } from "typeorm";
import * as ExcelJs from "exceljs";
import * as dayjs from "dayjs";
import { getTokenUserInfo, handleFindOptions } from "src/utils";
import { TeacherTitleEnum } from "src/enums/school/teacher.enum";
import { CreateTeacherDto } from "./dto/create-teacher.dto";
import { UpdateTeacherDto } from "./dto/update-teacher.dto";
import { Teacher } from "./entities/teacher.entity";
import { TeacherDetail } from "./entities/teacherDetail.entity";
import { CourseLabelMap } from "src/enums/school/course.enum";
import type { QueryType } from "src/types/index.types";
import type { Request } from "express";

// ! typeorm Repository 方式

@Injectable()
export class TeacherService {
  constructor(@InjectRepository(Teacher) private readonly teacherServer: Repository<Teacher>) {}

  async create(createTeacherDto: CreateTeacherDto, request: Request) {
    const token = request.get("authorization");
    let { teacherName, course, ...createDto } = { ...createTeacherDto };
    const teacher = new Teacher();
    let detail = new TeacherDetail();
    if (token) {
      const userInfo = getTokenUserInfo(token);
      teacher.createBy = userInfo.nickname;
      teacher.createById = userInfo.id;
    }
    teacher.teacherName = teacherName;
    teacher.course = course;
    detail = { ...detail, ...createDto };
    await this.teacherServer.save({ ...teacher, detail });
    return null;
  }

  async findAll(query?: QueryType) {
    const options: FindManyOptions = handleFindOptions(query || {});
    const { teacherName, teacherTitle,course } = query || {};
    if (teacherName) options.where = { teacherName: Like(`%${teacherName}%`) };
    if (teacherTitle) options.where = { teacherTitle };
    if (course) options.where = { course };
    options.relations = ["detail"];
    const [list, total] = await this.teacherServer.findAndCount(options);
    const rows = list.map(item => {
      const { detail, ...rest } = item;
      return { ...rest, ...detail };
    });
    return { rows, total };
  }

  async findTeacherAllOptions(query?: QueryType) {
    const options: FindManyOptions = handleFindOptions(query || {});
    const [list, total] = await this.teacherServer.findAndCount(options);
    const rows = list.map(item => ({ label: item.teacherName, value: item.id, type: item.course }));
    return { rows, total };
  }

  async findOne(id: number) {
    const teacher = await this.teacherServer.findOne({ where: { id }, relations: ["detail"] });
    if (!teacher) throw new HttpException("角色不存在", HttpStatus.BAD_REQUEST);
    return teacher;
  }

  async update(id: number, updateTeacherDto: UpdateTeacherDto, request: Request) {
    const teacher = await this.teacherServer.findOne({ where: { id } });
    if (!teacher) throw new HttpException("角色不存在", HttpStatus.BAD_REQUEST);
    const token = request.get("authorization");
    if (token) {
      const userInfo = getTokenUserInfo(token);
      teacher.updateBy = userInfo.nickname;
      teacher.updateById = userInfo.id;
    }
    Object.assign(teacher.detail, updateTeacherDto);
    await this.teacherServer.save(teacher);
    return null;
  }

  async remove(id: number) {
    const teacher = await this.teacherServer.findOne({ where: { id } });
    if (!teacher) throw new HttpException("角色不存在", HttpStatus.BAD_REQUEST);
    await this.teacherServer.remove(teacher);
    return null;
  }

  async export() {
    const workbook = new ExcelJs.Workbook();
    const worksheet = workbook.addWorksheet("教师表_" + +new Date()); // 设置表名
    // worksheet.properties.defaultColWidth = 30; // 默认宽度
    const { rows } = await this.findAll();
    // 设置列 这样可以设置宽度
    worksheet.columns = [
      { header: "教师名称", key: "teacherName", width: 14 },
      { header: "教师职称", key: "teacherTitle", width: 14 },
      { header: "负责课程", key: "course", width: 14 },
      { header: "性别", key: "gender", width: 7 },
      { header: "联系电话", key: "teacherPhone", width: 14 },
      { header: "现居地址", key: "currentAddress", width: 60 },
      { header: "身份证号码", key: "idCard", width: 20 },
      { header: "身份证地址", key: "idCardAddress", width: 60 },
      { header: "账号创建时间", key: "createDate", width: 18 },
    ];
    const list = rows.map(item => {
      return [
        item.teacherName,
        TeacherTitleEnum[item.teacherTitle],
        CourseLabelMap[item.course],
        item.gender === 1 ? "男" : "女",
        item.teacherPhone,
        item.currentAddress,
        item.idCard,
        item.idCardAddress,
        dayjs(item.createDate).format("YYYY-MM-DD HH:mm:ss"),
      ];
    });
    // 表格数据
    worksheet.addRows(list);
    // 设置第一行样式
    const row1 = worksheet.getRow(1);
    row1.font = { bold: true, size: 14, color: { argb: "4387FB" } };
    // 返回 buffer
    const buffer = await workbook.xlsx.writeBuffer();
    return buffer;
  }
}
